package com.furnitur.core.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.furnitur.common.api.CommonPage;
import com.furnitur.common.util.JwtTokenUtil;
import com.furnitur.core.entity.product.Furniture;
import com.furnitur.core.entity.user.Merchant;
import com.furnitur.core.entity.user.User;
import com.furnitur.core.mapper.order.OrderMapper;
import com.furnitur.core.mapper.product.FurnitureMapper;
import com.furnitur.core.mapper.user.MerchantMapper;
import com.furnitur.core.mapper.user.UserMapper;
import com.furnitur.core.service.FileService;
import com.furnitur.core.service.UserService;
import com.furnitur.modules.admin.dto.UserDTO;
import com.furnitur.modules.admin.dto.auth.LoginDTO;
import com.furnitur.modules.admin.dto.auth.PasswordUpdateDTO;
import com.furnitur.modules.admin.dto.auth.RegisterDTO;
import com.furnitur.modules.admin.dto.user.UserQueryDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

@Service
public class UserServiceImpl implements UserService {

    private static final Logger log = LoggerFactory.getLogger(UserServiceImpl.class);

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private MerchantMapper merchantMapper;

    @Autowired
    private FurnitureMapper furnitureMapper;

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    @Autowired
    private FileService fileService;

    @Value("${file.upload.dir}")
    private String uploadBaseDir;

    @Override
    @Transactional
    public User register(RegisterDTO registerDTO) {
        log.info("Registering new user: {}", registerDTO.getUsername());
        
        // 检查用户名是否已存在
        if (getUserByUsername(registerDTO.getUsername()) != null) {
            throw new RuntimeException("用户名已存在");
        }
        
        // 创建新用户
        User user = new User();
        user.setUsername(registerDTO.getUsername());
        user.setPassword(passwordEncoder.encode(registerDTO.getPassword()));
        user.setPhone(registerDTO.getPhone());
        
        // 设置角色
        if (registerDTO.getRoleType() == 0) {
            // 普通用户
            user.setRoleId(0L);
        } else if (registerDTO.getRoleType() == 1) {
            // 管理员
            user.setRoleId(1L);
        } else if (registerDTO.getRoleType() == 2) {
            // 商家
            user.setRoleId(2L);
            // 验证商家信息
            if (registerDTO.getMerchant() == null) {
                throw new RuntimeException("商家信息不能为空");
            }
        } else {
            throw new RuntimeException("无效的角色类型");
        }
        
        user.setStatus(1); // 默认启用
        log.info("Inserting user: {}", user);
        userMapper.insert(user);
        
        // 如果是商家，创建商家信息
        if (registerDTO.getRoleType() == 2) {
            log.info("Creating merchant for user: {}", user.getId());
            try {
                Merchant merchant = new Merchant();
                merchant.setUserId(user.getId());
                merchant.setShopName(registerDTO.getMerchant().getShopName());
                merchant.setDescription(registerDTO.getMerchant().getDescription());
                merchant.setAddress(registerDTO.getMerchant().getAddress());
                merchant.setBusinessLicense(registerDTO.getMerchant().getBusinessLicense());
                merchant.setStatus(1); // 直接设置为启用状态
                log.info("Inserting merchant: {}", merchant);
                int rows = merchantMapper.insert(merchant);
                log.info("Inserted merchant rows: {}", rows);
                
                if (rows != 1) {
                    throw new RuntimeException("创建商家信息失败");
                }
            } catch (Exception e) {
                log.error("Error creating merchant", e);
                throw new RuntimeException("创建商家信息失败: " + e.getMessage());
            }
        }
        
        return user;
    }

    @Override
    public String login(LoginDTO loginDTO) {
        User user = getUserByUsername(loginDTO.getUsername());
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        if (!passwordEncoder.matches(loginDTO.getPassword(), user.getPassword())) {
            throw new RuntimeException("密码错误");
        }
        
        return jwtTokenUtil.generateToken(user.getUsername());
    }

    @Override
    public User getUserByUsername(String username) {
        return userMapper.selectOne(new QueryWrapper<User>().eq("username", username));
    }

    @Override
    @Transactional
    public void updatePassword(Long userId, PasswordUpdateDTO passwordUpdate) {
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        // 验证旧密码
        if (!passwordEncoder.matches(passwordUpdate.getOldPassword(), user.getPassword())) {
            throw new RuntimeException("旧密码错误");
        }

        // 更新密码
        user.setPassword(passwordEncoder.encode(passwordUpdate.getNewPassword()));
        userMapper.updateById(user);
    }

    @Override
    public User getCurrentUser() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null) {
            throw new RuntimeException("用户未登录");
        }
        
        Object principal = authentication.getPrincipal();
        if (principal instanceof User) {
            return (User) principal;
        } else if (principal instanceof String) {
            String username = (String) principal;
            User user = getUserByUsername(username);
            if (user == null) {
                throw new RuntimeException("用户不存在");
            }
            return user;
        }
        
        throw new RuntimeException("用户未登录");
    }

    @Override
    public Long getCurrentMerchantId() {
        User currentUser = getCurrentUser();
        if (currentUser == null) {
            return null;
        }

        if (currentUser.getRoleId() != 2L) {
            return null;
        }

        Merchant merchant = merchantMapper.selectOne(
            new QueryWrapper<Merchant>()
                .eq("user_id", currentUser.getId())
        );

        return merchant != null ? merchant.getId() : null;
    }

    @Override
    public String uploadUserProfileImage(MultipartFile file) throws Exception {
        User currentUser = getCurrentUser();
        if (currentUser == null) {
            throw new RuntimeException("用户未登录");
        }

        // 上传文件
        String imageUrl = fileService.uploadImage(file);

        // 更新用户头像URL
        currentUser.setAvatar(imageUrl);
        userMapper.updateById(currentUser);

        return imageUrl;
    }

    @Override
    public String uploadAvatar(User user, MultipartFile file) {
        if (file == null || file.isEmpty()) {
            throw new IllegalArgumentException("文件不能为空");
        }

        // 获取文件扩展名
        String originalFilename = file.getOriginalFilename();
        String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
        if (!Arrays.asList(".jpg", ".jpeg", ".png", ".gif").contains(extension.toLowerCase())) {
            throw new IllegalArgumentException("只支持jpg、jpeg、png、gif格式的图片");
        }

        try {
            // 使用FileService上传到MinIO
            String imageUrl = fileService.uploadImage(file);
            
            // 更新用户头像URL
            User updateUser = new User();
            updateUser.setId(user.getId());
            updateUser.setAvatar(imageUrl);
            userMapper.updateById(updateUser);

            return imageUrl;
        } catch (Exception e) {
            log.error("上传头像失败", e);
            throw new RuntimeException("上传头像失败: " + e.getMessage());
        }
    }

    @Override
    public CommonPage<User> listUsers(UserQueryDTO queryDTO) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        
        // 添加搜索条件
        if (StringUtils.hasText(queryDTO.getKeyword())) {
            queryWrapper.and(wrapper -> wrapper
                    .like("username", queryDTO.getKeyword())
                    .or()
                    .like("nickname", queryDTO.getKeyword())
                    .or()
                    .like("phone", queryDTO.getKeyword())
                    .or()
                    .like("email", queryDTO.getKeyword()));
        }
        
        // 状态筛选
        if (queryDTO.getStatus() != null) {
            queryWrapper.eq("status", queryDTO.getStatus());
        }
        
        // 角色筛选
        if (queryDTO.getRoleId() != null) {
            queryWrapper.eq("role_id", queryDTO.getRoleId());
        } else {
            // 默认排除超级管理员
            queryWrapper.ne("role_id", 1L);
        }
        
        // 按创建时间降序排序
        queryWrapper.orderByDesc("created_at");
        
        // 分页查询
        Page<User> page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize());
        Page<User> userPage = userMapper.selectPage(page, queryWrapper);
        
        // 转换为通用分页对象
        return CommonPage.restPage(userPage);
    }

    @Override
    @Transactional
    public User createUser(UserDTO userDTO) {
        // 检查用户名是否已存在
        if (getUserByUsername(userDTO.getUsername()) != null) {
            throw new RuntimeException("用户名已存在");
        }

        User user = new User();
        BeanUtils.copyProperties(userDTO, user);
        
        // 设置默认密码
        if (userDTO.getPassword() == null || userDTO.getPassword().isEmpty()) {
            user.setPassword(passwordEncoder.encode("123456"));
        } else {
            user.setPassword(passwordEncoder.encode(userDTO.getPassword()));
        }
        
        // 设置默认状态为启用
        if (user.getStatus() == null) {
            user.setStatus(1);
        }
        
        userMapper.insert(user);
        return user;
    }

    @Override
    @Transactional
    public User updateUser(Long id, UserDTO userDTO) {
        User existingUser = userMapper.selectById(id);
        if (existingUser == null) {
            throw new RuntimeException("用户不存在");
        }

        // 如果修改了用户名，检查是否与其他用户重复
        if (!existingUser.getUsername().equals(userDTO.getUsername())) {
            User userByUsername = getUserByUsername(userDTO.getUsername());
            if (userByUsername != null && !userByUsername.getId().equals(id)) {
                throw new RuntimeException("用户名已存在");
            }
        }

        BeanUtils.copyProperties(userDTO, existingUser);
        existingUser.setId(id); // 确保ID不变

        // 如果提供了新密码，则更新密码
        if (userDTO.getPassword() != null && !userDTO.getPassword().isEmpty()) {
            existingUser.setPassword(passwordEncoder.encode(userDTO.getPassword()));
        }

        userMapper.updateById(existingUser);
        return existingUser;
    }

    @Override
    @Transactional
    public void deleteUser(Long id) {
        // 检查是否为当前用户
        User currentUser = getCurrentUser();
        if (currentUser.getId().equals(id)) {
            throw new RuntimeException("不能删除当前登录用户");
        }

        // 检查是否为超级管理员
        User user = userMapper.selectById(id);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        if (user.getRoleId() == 1) {
            throw new RuntimeException("不能删除超级管理员");
        }

        // 如果是商家，先删除商家的所有商品和商家记录
        if (user.getRoleId() == 2) {
            // 查找商家记录
            QueryWrapper<Merchant> merchantQueryWrapper = new QueryWrapper<>();
            merchantQueryWrapper.eq("user_id", id);
            Merchant merchant = merchantMapper.selectOne(merchantQueryWrapper);
            
            if (merchant != null) {
                // 删除商家的所有商品
                QueryWrapper<Furniture> furnitureQueryWrapper = new QueryWrapper<>();
                furnitureQueryWrapper.eq("merchant_id", merchant.getId());
                furnitureMapper.delete(furnitureQueryWrapper);
                
                // 删除商家记录
                merchantMapper.deleteById(merchant.getId());
            }
        }

        // 删除用户
        userMapper.deleteById(id);
    }

    @Override
    @Transactional
    public void deleteUsers(Long[] ids) {
        // 检查是否包含当前用户或超级管理员
        User currentUser = getCurrentUser();
        List<Long> idList = Arrays.asList(ids);
        
        if (idList.contains(currentUser.getId())) {
            throw new RuntimeException("不能删除当前登录用户");
        }

        // 检查是否包含超级管理员
        List<User> users = userMapper.selectBatchIds(idList);
        for (User user : users) {
            if (user.getRoleId() == 1) {
                throw new RuntimeException("不能删除超级管理员");
            }
        }

        // 处理商家用户
        for (User user : users) {
            if (user.getRoleId() == 2) {
                // 查找商家记录
                QueryWrapper<Merchant> merchantQueryWrapper = new QueryWrapper<>();
                merchantQueryWrapper.eq("user_id", user.getId());
                Merchant merchant = merchantMapper.selectOne(merchantQueryWrapper);
                
                if (merchant != null) {
                    // 删除商家的所有商品
                    QueryWrapper<Furniture> furnitureQueryWrapper = new QueryWrapper<>();
                    furnitureQueryWrapper.eq("merchant_id", merchant.getId());
                    furnitureMapper.delete(furnitureQueryWrapper);
                    
                    // 删除商家记录
                    merchantMapper.deleteById(merchant.getId());
                }
            }
        }

        // 批量删除用户
        userMapper.deleteBatchIds(idList);
    }

    @Override
    @Transactional
    public void updateUserStatus(Long id, Integer status) {
        User user = userMapper.selectById(id);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 不允许修改超级管理员状态
        if (user.getRoleId() == 1L) {
            throw new RuntimeException("不能修改超级管理员状态");
        }

        user.setStatus(status);
        userMapper.updateById(user);
    }
}